package de.preamp.clients.java.lib.ui;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;

import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.ListCellRenderer;
import javax.swing.SwingWorker;

import de.preamp.clients.java.data.Album;
import de.preamp.clients.java.data.Artist;
import de.preamp.clients.java.data.Track;

/**
 * @author André Stannek
 * @version 2010-03-21
 */
public class DBItemCellRenderer implements ListCellRenderer
{
    /**
     * Generated UID.
     */
    private static final long serialVersionUID = 3350388022281095477L;

    /**
     * The Panels used to display either artist, album or track information.
     */
    private JPanel artist, album, track;

    /**
     * Labels used on the artist panel.
     */
    private JLabel artistName, artistPicture;

    /**
     * Labels used on the album panel.
     */
    private JLabel albumTitle, albumTrackCount, albumLength, albumCover;

    /**
     * Labels used on the track panel.
     */
    private JLabel trackNo, trackLength, trackName;

    /**
     * Default Constructor.
     */
    public DBItemCellRenderer()
    {
        super();
        initArtistRenderer();
        initAlbumRenderer();
        initTrackRenderer();
    }

    /**
     * Constructor for an {@link DBItemCellRenderer} describing an artist.
     */
    private void initArtistRenderer()
    {
        artist = new JPanel();
        artistName = new JLabel();
        artistPicture = new JLabel();
        artist.setLayout(new FlowLayout(FlowLayout.LEFT));
        final JPanel info = new JPanel(new GridLayout(5, 1));
        info.add(artistName);
        // sizing
        final Dimension infoSize = new Dimension(200, 100);
        info.setPreferredSize(infoSize);
        final Dimension itemSize = new Dimension(300, 100);
        artist.setPreferredSize(itemSize);

        artist.add(artistPicture);
        artist.add(info);
    }

    /**
     * Constructor for an {@link DBItemCellRenderer} describing an album.
     */
    public final void initAlbumRenderer()
    {
        album = new JPanel();
        albumTitle = new JLabel();
        albumTrackCount = new JLabel();
        albumLength = new JLabel();
        albumCover = new JLabel();
        album.setLayout(new FlowLayout(FlowLayout.LEFT));
        final JPanel info = new JPanel(new GridLayout(5, 1));
        info.add(albumTitle);
        info.add(albumTrackCount);
        info.add(albumLength);
        // sizing
        final Dimension infoSize = new Dimension(200, 100);
        info.setPreferredSize(infoSize);
        final Dimension itemSize = new Dimension(300, 100);
        album.setPreferredSize(itemSize);

        album.add(albumCover);
        album.add(info);
    }

    /**
     * Constructor for an {@link DBItemCellRenderer} describing a track.
     */
    public final void initTrackRenderer()
    {
        track = new JPanel();
        trackNo = new JLabel();
        trackLength = new JLabel();
        trackName = new JLabel();
        track.setLayout(new BorderLayout());
        final JPanel info = new JPanel(new FlowLayout(FlowLayout.LEFT));

        info.add(trackNo);
        info.add(new JLabel(" - "));
        info.add(trackName);
        // sizing
        final Dimension itemSize = new Dimension(300, 20);
        track.setPreferredSize(itemSize);

        track.add(info, BorderLayout.WEST);
        track.add(trackLength, BorderLayout.EAST);
    }

    @Override
    public final Component getListCellRendererComponent(final JList list,
            final Object value, final int index, final boolean isSelected,
            final boolean cellHasFocus)
    {
        if (value instanceof Artist)
        {
            return artistCellRender((Artist) value);
        }
        if (value instanceof Album)
        {
            return albumCellRenderer((Album) value);
        }
        if (value instanceof Track)
        {
            return trackCellRenderer((Track) value);
        }
        else
        {
            return new JLabel("Displaying this item is not posible!");
        }
    }

    /**
     * Returns a rendered cell with information about an artist.
     * 
     * @param value
     *            the artist wichs infos should be displayed
     * @return the rendered cell
     */
    private Component artistCellRender(final Artist value)
    {
        final ImageIcon image = value.getPicture();

        if (image == null)
        {
            final SwingWorker<Void, Object> loadimages = new SwingWorker<Void, Object>()
            {
                @Override
                protected Void doInBackground() throws Exception
                {
                    value.loadPicture();
                    return null;
                }
            };
            loadimages.execute();
        }
        else
        {
            artistPicture.setIcon(image);
        }

        artistName.setText(value.getName());
        return artist;
    }

    /**
     * Returns a rendered cell with information about an album.
     * 
     * @param value
     *            the album wichs infos should be displayed
     * @return the rendered cell
     */
    private Component albumCellRenderer(final Album value)
    {
        albumTitle.setText(value.getTitle());
        albumTrackCount.setText(value.getTracks().size() + " tracks");
        albumLength.setText(value.getLengthAsString());

        final ImageIcon cover = value.getCover();

        if (cover == null)
        {
            final SwingWorker<Void, Object> loadimages = new SwingWorker<Void, Object>()
            {
                @Override
                protected Void doInBackground() throws Exception
                {
                    value.loadCover();
                    return null;
                }
            };
            loadimages.execute();
        }
        else
        {
            albumCover.setIcon(cover);
        }

        return album;
    }

    /**
     * Returns a rendered cell with information about a track.
     * 
     * @param value
     *            the track wichs infos should be displayed
     * @return the rendered cell
     */
    private Component trackCellRenderer(final Track value)
    {
        final StringBuilder number = new StringBuilder();
        if (value.getTrack() < 10)
        {
            number.append(0);
        }
        number.append(value.getTrack());

        trackNo.setText(number.toString());
        trackLength.setText(value.getLengthAsString());
        trackName.setText(value.getTitle());
        return track;
    }
}
